package eval

import (
	"fmt"
	"showen/lex"
	"showen/obj"
	"showen/parse"
)

// VerifyComplexFunctions tests the make-rectangular and make-polar functions
func VerifyComplexFunctions() {
	fmt.Println("Testing make-rectangular and make-polar functions")

	env := obj.NewEnvironment()
	RegisterBuiltinProcedures(env)

	// Test make-rectangular
	testCases := []string{
		"(make-rectangular 3 4)",
		"(make-rectangular 1 0)",
		"(make-rectangular 0 1)",
		"(make-rectangular -2 5)",
		"(make-polar 1 0)",
		"(make-polar 1 1.5707963267948966)", // π/2
		"(make-polar 2 0)",
	}

	for _, test := range testCases {
		lexer := lex.NewLexer(test)
		tokens := lexer.ReadTokens()
		parser := parse.NewParser(tokens)
		expr, err := parser.ParseExpression()
		if err != nil {
			fmt.Printf("Error parsing %s: %v\n", test, err)
			continue
		}

		result, err := EvalExpression(expr, env)
		if err != nil {
			fmt.Printf("Error evaluating %s: %v\n", test, err)
			continue
		}

		fmt.Printf("%s = %s\n", test, result.Inspect())
	}
}

// VerifyMagnitudeAndAngleFunctions tests the magnitude and angle functions
func VerifyMagnitudeAndAngleFunctions() {
	fmt.Println("Testing magnitude and angle functions")

	env := obj.NewEnvironment()
	RegisterBuiltinProcedures(env)

	// Test magnitude and angle
	testCases := []string{
		"(magnitude 5)",
		"(magnitude -5)",
		"(magnitude (make-rectangular 3 4))",
		"(magnitude (make-rectangular 5 12))",
		"(angle 5)",
		"(angle -5)",
		"(angle (make-rectangular 1 1))",
		"(angle (make-rectangular 0 1))",
		"(angle (make-rectangular -1 0))",
	}

	for _, test := range testCases {
		lexer := lex.NewLexer(test)
		tokens := lexer.ReadTokens()
		parser := parse.NewParser(tokens)
		expr, err := parser.ParseExpression()
		if err != nil {
			fmt.Printf("Error parsing %s: %v\n", test, err)
			continue
		}

		result, err := EvalExpression(expr, env)
		if err != nil {
			fmt.Printf("Error evaluating %s: %v\n", test, err)
			continue
		}

		fmt.Printf("%s = %s\n", test, result.Inspect())
	}
}

// VerifyExactInexactFunctions tests the exact->inexact and inexact->exact functions
func VerifyExactInexactFunctions() {
	fmt.Println("Testing exact->inexact and inexact->exact functions")

	env := obj.NewEnvironment()
	RegisterBuiltinProcedures(env)

	// Test exact->inexact and inexact->exact
	testCases := []string{
		"(exact->inexact 5)",
		"(exact->inexact 1/2)",
		"(exact->inexact 3/4)",
		"(inexact->exact 5.0)",
		"(inexact->exact 0.5)",
		"(inexact->exact 0.75)",
		"(exact->inexact (make-rectangular 3 4))",
		"(inexact->exact (make-rectangular 1.0 2.0))",
	}

	for _, test := range testCases {
		lexer := lex.NewLexer(test)
		tokens := lexer.ReadTokens()
		parser := parse.NewParser(tokens)
		expr, err := parser.ParseExpression()
		if err != nil {
			fmt.Printf("Error parsing %s: %v\n", test, err)
			continue
		}

		result, err := EvalExpression(expr, env)
		if err != nil {
			fmt.Printf("Error evaluating %s: %v\n", test, err)
			continue
		}

		fmt.Printf("%s = %s\n", test, result.Inspect())
	}
}

// VerifyExactPredicateWithComplex tests the exact? function with complex numbers
func VerifyExactPredicateWithComplex() {
	fmt.Println("Testing exact? with complex numbers")

	env := obj.NewEnvironment()
	RegisterBuiltinProcedures(env)

	// Test exact? with complex numbers
	testCases := []string{
		"(exact? 3+4i)",
		"(exact? 1/2+3/4i)",
		"(exact? 1.0+2.0i)",
		"(exact? (make-rectangular 3 4))",
		"(exact? (make-rectangular 1/2 3/4))",
		"(exact? (make-rectangular 1.0 2.0))",
		"(exact? 5)",
		"(exact? 1/2)",
		"(exact? 1.5)",
	}

	for _, test := range testCases {
		lexer := lex.NewLexer(test)
		tokens := lexer.ReadTokens()
		parser := parse.NewParser(tokens)
		expr, err := parser.ParseExpression()
		if err != nil {
			fmt.Printf("Error parsing %s: %v\n", test, err)
			continue
		}

		result, err := EvalExpression(expr, env)
		if err != nil {
			fmt.Printf("Error evaluating %s: %v\n", test, err)
			continue
		}

		fmt.Printf("%s = %s\n", test, result.Inspect())
	}
}

// VerifyInexactPredicateWithComplex tests the inexact? function with complex numbers
func VerifyInexactPredicateWithComplex() {
	fmt.Println("Testing inexact? with complex numbers")

	env := obj.NewEnvironment()
	RegisterBuiltinProcedures(env)

	// Test inexact? with complex numbers
	testCases := []string{
		"(inexact? 3.0+4i)",
		"(inexact? 3+4.0i)",
		"(inexact? 3.0+4.0i)",
		"(inexact? 3+4i)",
		"(inexact? 1/2+3/4i)",
		"(inexact? 1.0+2.0i)",
		"(inexact? (make-rectangular 3.0 4))",
		"(inexact? (make-rectangular 3 4.0))",
		"(inexact? (make-rectangular 3.0 4.0))",
		"(inexact? (make-rectangular 3 4))",
		"(inexact? 5.0)",
		"(inexact? 5)",
		"(inexact? 1/2)",
	}

	for _, test := range testCases {
		lexer := lex.NewLexer(test)
		tokens := lexer.ReadTokens()
		parser := parse.NewParser(tokens)
		expr, err := parser.ParseExpression()
		if err != nil {
			fmt.Printf("Error parsing %s: %v\n", test, err)
			continue
		}

		result, err := EvalExpression(expr, env)
		if err != nil {
			fmt.Printf("Error evaluating %s: %v\n", test, err)
			continue
		}

		fmt.Printf("%s = %s\n", test, result.Inspect())
	}
}
